package com.entrogy.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.entrogy.bean.*;
import com.entrogy.dao.*;
import com.entrogy.service.StudentScoreService;
import com.entrogy.utils.SendUtils;
import com.entrogy.utils.StrUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName StudentScoreServiceImpl
 * @Description
 * @Author luoxingjiang
 * @Date 2019/6/4 0004 下午 4:31
 * @Version 1.0
 **/
@Service
public class StudentScoreServiceImpl implements StudentScoreService {

    private static final Logger logger = LoggerFactory.getLogger(StudentScoreServiceImpl.class);

    @Autowired
    private StudentScoreMapper studentScoreMapper;

    @Autowired
    private ParentMapper parentMapper;

    @Autowired
    private ExamMapper examMapper;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private SchoolMapper schoolMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private CourseMapper courseMapper;


    /**
     * 查找某次考试所有学生的考试成绩
     * @param examId
     * @param classType
     * @param classId
     * @param scoreTableName
     * @param schoolCode
     * @param exportScore 学生的成绩列表是否用于导出excel，当用于导出excel时，不需要班级年级排名，并且学生列表的成绩列表不需要按照总分排序
     * @param studentId
     * @return
     */
    @Override
    public List<StudentScoreEntity> findStudentScoreList(Integer examId, Integer classType, Integer classId, String scoreTableName, Integer schoolCode, boolean exportScore, Integer studentId) {
        List<StudentScoreEntity> studentScoreList = studentScoreMapper.findStudentScoreList(examId, classType, classId, scoreTableName, schoolCode, exportScore, studentId);
        return studentScoreList;
    }

    @Override
    public List<StudentCourseScoreEntity> findStudentCourseScoreList(Map<String, Object> param) {
        return studentScoreMapper.findStudentCourseScoreList(param);
    }

    /**
     * 录入分数
     * @param studentCourseScoreEntities
     * @return
     */
    @Override
    public boolean updateScore(List<StudentCourseScoreEntity> studentCourseScoreEntities) {
        String scoreTableName = examMapper.findScoreTableNameByExamId(studentCourseScoreEntities.get(0).getExamId());
        int row = studentScoreMapper.updateStuCourseScore(scoreTableName,studentCourseScoreEntities);
        return row > 0;
    }

    /**
     * 查找某次考试的班级成绩概览
     * @param examId
     * @param classId
     * @param gradeId
     * @param scoreTableName
     * @return
     */
    @Override
    public List<ClassScoreOverviewEntity> findClassScoreOverviewList(Integer examId, Integer classId, Integer gradeId, String scoreTableName) {
        List<ClassScoreOverviewEntity> classScoreOverviewList = studentScoreMapper.findClassScoreOverviewList(examId, classId, scoreTableName);
        for (int i = 0; i < classScoreOverviewList.size(); i++) {
            ClassScoreOverviewEntity classScoreOverviewEntity = classScoreOverviewList.get(i);
            Integer courseId = classScoreOverviewEntity.getCourseId();
            // 将年级平均分设置进班级分数概览中
            classScoreOverviewEntity.setGradeAvgScore(studentScoreMapper.findGradeAvgScore(examId, courseId, gradeId, scoreTableName));
            // 将某一科的班级/年级中位分设置静班级分数概览中
            ExamCourseInfoEntity examCourseInfoEntity = examMapper.getExamCourseInfo(examId, courseId);
            classScoreOverviewEntity.setClassMiddleScore(examCourseInfoEntity.getClassMiddleScore()).setGradeMiddleScore(examCourseInfoEntity.getGradeMiddleScore());
            // 将年级平均分排名设置进班级分数概览中
            Map<String, Object> param = new HashMap<>();
            param.put("scoreTableName", scoreTableName);
            param.put("examId", examId);
            param.put("gradeId", gradeId);
            Integer staticCourseId = classScoreOverviewEntity.getStaticCourseId();
            param.put("staticCourseId", staticCourseId);
            param.put("classId", classId);
            classScoreOverviewEntity.setClassRank(studentScoreMapper.findClassRankForCourse(param));
        }
        return classScoreOverviewList;
    }

    @Override
    public List<JSONObject> findStudentScoreListForExport(Integer examId, List<StaticCourseEntity> staticCourses, String scoreTableName) {
        return studentScoreMapper.findStudentScoreListForExport(examId, staticCourses, scoreTableName);
    }

    /**
     * 查找某次考试的静态课程
     * @param examId
     * @return
     */
    @Override
    public List<StaticCourseEntity> findExamStaticCourse(Integer examId) {
        return studentScoreMapper.findExamStaticCourse(examId);
    }

    @Override
    public Integer findCourseIdByStaticId(Integer staticCourseId, Integer examId, Integer studentId) {
        return studentScoreMapper.findCourseIdByStaticId(staticCourseId, examId, studentId);
    }

    @Override
    public boolean updateScoreByImport(String scoreTableName, StudentCourseScoreEntity studentCourseScoreEntity) {
        return studentScoreMapper.updateScoreByImport(scoreTableName, studentCourseScoreEntity) > 0;
    }

    @Override
    public Map<String, Object> sendWeApp(Integer type, Integer sendMethod, Integer examId, String scoreTableName, Integer schoolCode, Integer[] sendClassId) {
        // 判断该学校是否处于试运行状态
        Integer openStatus = schoolMapper.getSchoolOpenStatus(schoolCode);
        // 成绩发送失败的学生列表
        List<JSONObject> sendFailList = new ArrayList<>();
        // 成绩发送成功的学生列表
        List<JSONObject> sendSuccessList = new ArrayList<>();
        // 查询考试信息
        ExamEntity examEntity = examMapper.getExamInfo(examId);
        String examName = examEntity.getExamName();
        // 以班级为单位发送成绩
        for (int k = 0; k < sendClassId.length; k++) {
            Integer examClassId = sendClassId[k];
            // 查找出这个学生此次考试的科目成绩详情
            List<StudentScoreEntity> studentScoreList = findStudentScoreList(examId, null, examClassId, scoreTableName, schoolCode, false, null);
            // 首先查询出此次考试这个班的科目成绩的平均分
//            List<ClassScoreOverviewEntity> classScoreOverviewList = findClassScoreOverviewList(examId, examClassId, null, scoreTableName);
            for (int i = 0; i < studentScoreList.size(); i++) {
                // TODO 备注：新版本的短信消息以及微信公众号消息均不显示成绩详情，必须进入小程序才能查看
//                StringBuilder scoreInfo = new StringBuilder();
//                List<ScoreDetailEntity> scoreDetailEntities = studentScoreList.get(i).getScoreDetailEntities();
//                // 将学生的考试详情拼接为字符串
//                for (int j = 0; j < scoreDetailEntities.size(); j++) {
//                    ScoreDetailEntity temp = scoreDetailEntities.get(j);
//                    switch (type) {
//                        case 1:
//                            // 模板1，分数+班级排名
//                            scoreInfo.append(temp.getCourseName()).append(temp.getScore()).append("，").append(temp.getCourseName() + "班级名次" + temp.getCourseClassRank() + "；");
//                            break;
//                        case 2:
//                            // 模板2，分数
//                            scoreInfo.append(temp.getCourseName()).append(temp.getScore()).append("；");
//                            break;
//                        case 3:
//                            // 模板3，分数+班级平均+班级排名
//                            scoreInfo.append(temp.getCourseName()).append(temp.getScore()).append("，");
//                            for (int h = 0; h < classScoreOverviewList.size(); h++) {
//                                ClassScoreOverviewEntity classScore = classScoreOverviewList.get(h);
//                                if (classScore.getCourseId().equals(temp.getCourseId())){
//                                    scoreInfo.append(temp.getCourseName() + "班级平均分：" + classScore.getClassAvgScore() + "，");
//                                }
//                            }
//                            scoreInfo.append(temp.getCourseName() + "班级名次" + temp.getCourseClassRank() + "；");
//                            break;
//                        case 4:
//                            // 模板4，分数+班级平均
//                            scoreInfo.append(temp.getCourseName()).append(temp.getScore()).append("，");
//                            for (int h = 0; h < classScoreOverviewList.size(); h++) {
//                                ClassScoreOverviewEntity classScore = classScoreOverviewList.get(h);
//                                if (classScore.getCourseId().equals(temp.getCourseId())){
//                                    scoreInfo.append(temp.getCourseName() + "班级平均分：" + classScore.getClassAvgScore()  + "；");
//                                }
//                            }
//                            break;
//                    }
//                }
//                switch (type) {
//                    case 1:
//                        scoreInfo.append("总分：" + studentScoreList.get(i).getStudentTotalScore() + "总分班级排名：" + studentScoreList.get(i).getClassRank());
//                        break;
//                    case 2:
//                        scoreInfo.append("总分：" + studentScoreList.get(i).getStudentTotalScore() + "总分班级排名：" + studentScoreList.get(i).getClassRank());
//                        break;
//                    case 3:
//                        scoreInfo.append("总分：" + studentScoreList.get(i).getStudentTotalScore() + "总分班级排名：" + studentScoreList.get(i).getClassRank());
//                        break;
//                    case 4:
//                        // 班级总分平均分
//                        double classAvgScoreTotal = 0;
//                        for (int h = 0; h < classScoreOverviewList.size(); h++) {
//                            ClassScoreOverviewEntity classScore = classScoreOverviewList.get(h);
//                            classAvgScoreTotal += classScore.getClassAvgScore();
//                        }
//                        scoreInfo.append("总分：" + studentScoreList.get(i).getStudentTotalScore() + "总分班级平均分：" + classAvgScoreTotal +  "总分班级排名" + studentScoreList.get(i).getClassRank());
//                        break;
//                }
                // 成绩信息拼接完成后开始发送
                String studentName = studentScoreList.get(i).getStudentName();
//                String content =studentName + "本次《" + examEntity.getExamName() + "》考试成绩如下：" + scoreInfo;
                String content = studentName + "本次《" + examEntity.getExamName() + "》考试成绩已经发布，请各位家长登录《脸卡通》小程序查看孩子的成绩详情，";
                logger.info("正在发送的学生成绩=>" + content);
                // 如果发送方式为2（脸卡通+短信），其他发送方式均会发送到脸卡通
                Integer studentId = studentScoreList.get(i).getStudentId();
                if (openStatus == 0){
                    // 判断该孩子的通知服务是否开启
                    PayOrderEntity payOrderEntity = studentMapper.getStudentPayStatus(studentId);
                    if (payOrderEntity == null){
                        logger.info("学生ID=>" + studentId + "学生姓名=>" + studentName + "未开通通知服务，不会收到此次的成绩通知");
                        // 发送失败列表用于测试使用
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("studentName", studentName);
                        jsonObject.put("className", studentScoreList.get(i).getClassName());
                        sendFailList.add(jsonObject);
                        continue;
                    }else {
                        // 发送成功列表用于测试使用
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("studentName", studentName);
                        jsonObject.put("className", studentScoreList.get(i).getClassName());
                        sendSuccessList.add(jsonObject);
                    }
                }

                List<String> parentPhones = parentMapper.findParentPhoneByStudentId(studentId);
                for(String phone : parentPhones){
                    PubCountEntity pubCountEntity = messageMapper.getPubCountOpenidByPhone(phone);
                    String schoolName = schoolMapper.getSchoolName(schoolCode);
                    String[] paramsWeiXin = { "", schoolName, "系统通知", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), content, "" };
                    if (null != pubCountEntity && !StrUtils.isNullOrEmpty(pubCountEntity.getOpenid()))
                        SendUtils.sendByWeixinAndPath(pubCountEntity, paramsWeiXin, pubCountEntity.getTemplateId(), "packageA/pages/score/scoreList");
                    if (sendMethod == 2){
                        // 该生没有留有父母的电话号码的话，那么加入失败列表
                        String[] paramsMobile = new String[2];
                        paramsMobile[0] = content;
                        // 适配该家长通知的短信模板
                        paramsMobile[1] = "";
                        SendUtils.sendByShortMessage(phone, paramsMobile, "224729");
                    }
                }
            }
        }
        Map<String, Object> result = new HashMap<>();
        result.put("sendFailList", sendFailList);
        result.put("sendSuccessList", sendSuccessList);
        return result;
    }

    @Override
    @Transactional
    public boolean generateStuCourseClassRank(Integer examId, String scoreTableName, Integer requireCourseClassRank, Integer requireCourseGradeRank) {
        // 首先查找该次考试的所有科目
        List<Integer> examCourseIds = examMapper.findExamCourseIds(examId);
        for (int i = 0; i < examCourseIds.size(); i++) {
            Integer courseId = examCourseIds.get(i);
            // 单科班级排名
            List<StudentCourseScoreEntity> studentCourseScoreEntities = examMapper.findOrderByCourseScore(courseId, examId, scoreTableName);
            if (requireCourseClassRank == 1){
                int updateBatchCourseClassRankRow = studentScoreMapper.updateBatchCourseClassRank(studentCourseScoreEntities, scoreTableName);
            }
            // 单科所有考了此次考试的学生的整体排名
            if (requireCourseGradeRank == 1){
                CourseEntity courseEntity = courseMapper.getCourseEntity(courseId);
                studentCourseScoreEntities = examMapper.listCourseGradeRank(courseEntity.getStaticId(), examId, scoreTableName);
                int updateBatchCourseGradeRankRow = studentScoreMapper.updateBatchCourseGradeRank(studentCourseScoreEntities, scoreTableName);
            }
        }
        return true;
    }

    /**
     * 成绩排名更新版，使用排名后存入数据库的数据，而不是计算
     * @param examId
     * @param classType
     * @param classId
     * @param scoreTableName
     * @param schoolCode
     * @param exportScore
     * @param studentId
     * @return
     */
    @Override
    public List<StudentScoreEntity> findStudentScoreListByRank(Integer examId, Integer classType, Integer classId, String scoreTableName, Integer schoolCode, boolean exportScore, Integer studentId) {
        List<StudentScoreEntity> studentScoreList = studentScoreMapper.findStudentScoreList(examId, classType, classId, scoreTableName, schoolCode, exportScore, studentId);
        return studentScoreList;
    }

    @Override
    public boolean generateStuTotalScoreClassRank(Integer examId, String scoreTableName, Integer  requireTotalScoreClassRank) {
        //查找此次考试的班级
        List<Integer> examClassIds = examMapper.listExamClassId(examId);
        //将班级排名后的详细信息查询出来了然后存入数据
        for (int i = 0; i < examClassIds.size(); i++){
            int classId = examClassIds.get(i);
            List<StudentExamRankEntity> studentExamRankList = studentScoreMapper.listStudentClassRank(examId, classId, scoreTableName);
            for (StudentExamRankEntity studentExamRank : studentExamRankList) {
                //更新每个学生的班级排名信息（当需要生成班级排名才更新班级排名信息，不需要的话置位null）
                if (requireTotalScoreClassRank == 0)
                    studentExamRank.setClassRank(null);
                Integer row = studentScoreMapper.updateStudentClassRank(studentExamRank);
            }
        }
        return true;
    }

    @Override
    public boolean generateStuTotalScoreGradeRank(Integer examId, String scoreTableName) {
        List<StudentExamRankEntity> studentExamRankList = studentScoreMapper.getStudentGradeRank(examId, scoreTableName);
        for (StudentExamRankEntity studentExamRank : studentExamRankList) {
            //更新每个学生的年级排名信息
            int row = studentScoreMapper.updateStudentGradeRank(studentExamRank);
        }
        return true;
    }

    @Override
    public boolean generateCourseClassMiddleScore(Integer examId, String scoreTableName) {
        // 得到考试的科目id
        List<Integer> examCourseIds = examMapper.findExamCourseIds(examId);
        for (Integer examCourseId : examCourseIds) {
            // 单科班级中位分
            double courseClassMiddleScore;
            // 单科班级中位分的位置
            int courseClassMiddlePosition;
            // 通过考试科目id找到该班该科目的所有考试成绩
            List<Double> courseScore = examMapper.listExamCourseScore(examId, examCourseId, scoreTableName);
            if (courseScore.size() % 2 == 0){
                courseClassMiddlePosition = courseScore.size() / 2;
                courseClassMiddleScore = (courseScore.get(courseClassMiddlePosition) + courseScore.get(courseClassMiddlePosition - 1)) / 2;
            }else {
                courseClassMiddlePosition = courseScore.size() / 2;
                courseClassMiddleScore = courseScore.get(courseClassMiddlePosition);
            }
            int updateCourseClassMiddleScoreRow = examMapper.updateCourseClassMiddleScore(examId, examCourseId, courseClassMiddleScore);
        }
        return true;
    }

    @Override
    public boolean generateCourseGradeMiddleScore(Integer examId, String scoreTableName) {
        // 得到考试的科目id
        List<Integer> examCourseIds = examMapper.findExamCourseIds(examId);
        for (Integer examCourseId : examCourseIds) {
            // 得到静态科目id
            String courseStaticId = courseMapper.getCourseEntity(examCourseId).getStaticId();
            // 单科年级中位分
            double courseGradeMiddleScore;
            // 单科年级中位分的位置
            int courseGradeMiddlePosition;
            // 通过考试科目id找到该年级该科目的所有考试成绩
            List<Double> courseScore = examMapper.listExamCourseScoreForAll(examId, courseStaticId, scoreTableName);
            if (courseScore.size() % 2 == 0){
                courseGradeMiddlePosition = courseScore.size() / 2;
                courseGradeMiddleScore = (courseScore.get(courseGradeMiddlePosition) + courseScore.get(courseGradeMiddlePosition - 1)) / 2;
            }else {
                courseGradeMiddlePosition = courseScore.size() / 2;
                courseGradeMiddleScore = courseScore.get(courseGradeMiddlePosition);
            }
            int updateCourseGradeMiddleScoreRow = examMapper.updateCourseGradeMiddleScore(examId, examCourseId, courseGradeMiddleScore);
        }
        return true;
    }

    @Override
    public boolean batchUpdateScore(List<StudentCourseScoreEntity> studentCourseScoreList, String scoreTableName) {
//        for (StudentCourseScoreEntity studentCourseScoreEntity : studentCourseScoreList) {
//            boolean result = updateScoreByImport(scoreTableName, studentCourseScoreEntity);
//            logger.info("正在进行学生成绩导入=》" + studentCourseScoreEntity + "导入结果：" + result);
//            if(!result){
//                logger.error("成绩解析后插入出错");
//                return false;
//            }
//        }
        // 一条一条成绩的更新更改为批量更新提升效率
        if (studentCourseScoreList.size() > 0)
            examMapper.batchUpdateScore(studentCourseScoreList, scoreTableName);
        return true;
    }

    @Override
    public boolean generateScienceOrArts(Integer examId, String scoreTableName) {
        List<StudentBasicInfoEntity> studentList = examMapper.listExamStudent(examId);
        //定义文综 理综科目
        List<String> arts = Arrays.asList("历史", "地理", "政治");
        List<String> science = Arrays.asList("物理", "生物", "化学");
        //文科科目id
        List<Integer> artsCourseId = new ArrayList<>();
        //理科科目id
        List<Integer> scienceCourseId = new ArrayList<>();
        // 需要计算理综/文综的科目id
        List<Integer> cultureStaticCourseId = new ArrayList<>();
        // 查询此次考试的静态科目，当同时考了历史、政治、地理或者同时考了物理、化学、生物的时候才生成理综/文综成绩
        List<CourseEntity> examCourseList = examMapper.listExamCourse(examId);
        for (CourseEntity examCourse : examCourseList) {
            String courseName = examCourse.getCourseName();
            if ("历史".equals(courseName) || "政治".equals(courseName)
            || "地理".equals(courseName) || "物理".equals(courseName)
            || "化学".equals(courseName) || "生物".equals(courseName)){
                    if (arts.contains(courseName)) {
                        artsCourseId.add(Integer.valueOf(examCourse.getCourseId()));
                    }else{
                        scienceCourseId.add(Integer.valueOf(examCourse.getCourseId()));
                    }
            }
        }
        cultureStaticCourseId.addAll(scienceCourseId);
        cultureStaticCourseId.addAll(artsCourseId);
        if (artsCourseId.size() == 3 && cultureStaticCourseId.size() == 3){//这是文综成绩
            ArtsOrScienceTotalSorce(examId, scoreTableName, studentList, artsCourseId);
            return true;
        }else if (scienceCourseId.size() == 3 && cultureStaticCourseId.size() == 3){//这是理综成绩
            ArtsOrScienceTotalSorce(examId, scoreTableName, studentList, scienceCourseId);
            return true;
        }else if (cultureStaticCourseId.size() > 3){//排除理综 文综的其他情况
            ArtsOrScienceTotalSorce(examId, scoreTableName, studentList, cultureStaticCourseId);
            return true;
        }else {
            return false;
        }
    }
    /**
     * 学生的文综或者理综的总成绩
     * @param examId
     * @param scoreTableName
     * @param artsOrScienceCourseId
     * @param studentList
     */
    private void ArtsOrScienceTotalSorce(Integer examId, String scoreTableName, List<StudentBasicInfoEntity> studentList, List<Integer> artsOrScienceCourseId) {
        for (StudentBasicInfoEntity student : studentList) {
            // 查询该学生文综或理综的总和并入库
            Double TotalScore = studentScoreMapper.getStudentExamCourseScore(student.getId(), examId, artsOrScienceCourseId, scoreTableName);
            int updateScienctArtsTotalScore = studentScoreMapper.updateScienceArtsTotalScore(student.getId(), examId, TotalScore);
        }
    }

    @Override
    public boolean generateScienceOrArtsRank(Integer examId, String scoreTableName, Integer requireScienceOrArtsClassRank, Integer requireScienceOrArtsGradeRank) {
        // 查询某次考试某年级的学生文综/理综成绩排名并更新
        if (requireScienceOrArtsGradeRank == 1){
            List<StudentExamRankEntity> studentExamRankList = studentScoreMapper.listStudentScienceOrArtsGradeRank(examId);
            for (StudentExamRankEntity studentExamRank : studentExamRankList) {
                int row = studentScoreMapper.updateStudentRank(studentExamRank);
            }
        }
        if (requireScienceOrArtsClassRank == 1){
            //查找此次考试的班级
            List<Integer> examClassIds = examMapper.listExamClassId(examId);
            // 查询某次考试某班级级的学生文综/理综成绩排名并更新
            for (Integer examClassId : examClassIds) {
                List<StudentExamRankEntity> studentExamScienceRankList = studentScoreMapper.listStudentScienceOrArtsClassRank(examId, examClassId);
                for (StudentExamRankEntity studentExamRank : studentExamScienceRankList) {
                    int row = studentScoreMapper.updateStudentRank(studentExamRank);
                }
            }
        }

        return true;
    }


}
